package com.jinzhi.jinzhidata.controller;

import com.jinzhi.jinzhidata.dataobject.ResourceType;
import com.jinzhi.jinzhidata.enums.ResourceStateEnum;
import com.jinzhi.jinzhidata.service.ResourceTypeService;
import com.jinzhi.jinzhidata.util.JwtUtil;
import com.jinzhi.jinzhidata.dataobject.Order;
import com.jinzhi.jinzhidata.service.OrderService;
import com.jinzhi.jinzhidata.util.Constant;
import com.jinzhi.jinzhidata.util.UUIDUtil;
import com.jinzhi.jinzhidata.vo.ResourceDetailVO;
import com.jinzhi.jinzhidata.vo.ListResourceVO;
import com.jinzhi.jinzhidata.vo.ResultVO;
import com.jinzhi.jinzhidata.dataobject.Resource;
import com.jinzhi.jinzhidata.dataobject.User;
import com.jinzhi.jinzhidata.enums.ResultEnum;
import com.jinzhi.jinzhidata.service.ResourceService;
import com.jinzhi.jinzhidata.service.UserService;
import com.jinzhi.jinzhidata.util.ResultVOUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author vansl
 * @description
 * @date 2019-12-29 13:26
 **/
@RequestMapping("/resource")
@Controller
public class ResourceController {

    @Autowired
    ResourceService resourceService;

    @Autowired
    ResourceTypeService resourceTypeService;

    @Autowired
    UserService userService;

    @Autowired
    OrderService orderService;

    @GetMapping("/list")
    @ResponseBody
    public ResultVO resourceList(@RequestParam(required = false) String typeName, Integer page, Integer size) {
        Sort sort = Sort.by(Sort.Direction.DESC, "updateTime");
        PageRequest pageRequest = PageRequest.of(page, size, sort);
        List<ListResourceVO> listResourceVOList = resourceService.selectResourceListByType(typeName, pageRequest);
        listResourceVOList.forEach(listResourceVO -> {
            listResourceVO.setResourcePrice(listResourceVO.getResourcePrice().multiply(Constant.POINT_CASH_RATE));
        });
        return ResultVOUtil.success(listResourceVOList);
    }

    @GetMapping("/list/like")
    @ResponseBody
    public ResultVO searchResourceByName(String resourceName, Integer page, Integer size) {
        Sort sort = Sort.by(Sort.Direction.DESC, "updateTime");
        PageRequest pageRequest = PageRequest.of(page, size, sort);
        List<ListResourceVO> listResourceVOList = resourceService.searchResourceByName(resourceName, pageRequest);
        listResourceVOList.forEach(listResourceVO -> {
            listResourceVO.setResourcePrice(listResourceVO.getResourcePrice().multiply(Constant.POINT_CASH_RATE));
        });
        return ResultVOUtil.success(listResourceVOList);
    }

    @GetMapping("/type/list")
    @ResponseBody
    public ResultVO resourceTypeList() {
        List<ResourceType> resourceTypeList = resourceTypeService.selectResourceTypeList();
        return ResultVOUtil.success(resourceTypeList);
    }

    @GetMapping("/list/upload")
    @ResponseBody
    public ResultVO userUploadResourceList(HttpServletRequest request, HttpServletResponse response) {
        String userId = JwtUtil.verifyAccessToken(request, response);
        if (StringUtils.isEmpty(userId)) {
            return ResultVOUtil.error(ResultEnum.NOT_LOGIN);
        }
        List<ListResourceVO> listResourceVOList = resourceService.selectResourceListByAuthor(userId);
        listResourceVOList.forEach(listResourceVO -> {
            listResourceVO.setResourcePrice(listResourceVO.getResourcePrice().multiply(Constant.POINT_CASH_RATE));
        });
        return ResultVOUtil.success(listResourceVOList);
    }

    @GetMapping("/list/buy")
    @ResponseBody
    public ResultVO userBuyResourceList(HttpServletRequest request, HttpServletResponse response) {
        String userId = JwtUtil.verifyAccessToken(request, response);
        if (StringUtils.isEmpty(userId)) {
            return ResultVOUtil.error(ResultEnum.NOT_LOGIN);
        }
        List<String> resourceIdList = orderService.selectGoodsIdListByUser(userId);
        List<ListResourceVO> listResourceVOList = resourceService.selectUserBuyResourceList(resourceIdList);
        listResourceVOList.forEach(listResourceVO -> {
            listResourceVO.setResourcePrice(listResourceVO.getResourcePrice().multiply(Constant.POINT_CASH_RATE));
        });
        return ResultVOUtil.success(listResourceVOList);
    }

    @GetMapping(value = "/{resourceId}")
    @ResponseBody
    public ResultVO showResource(@PathVariable String resourceId) {
        if (StringUtils.isEmpty(resourceId)) {
            return ResultVOUtil.error(ResultEnum.NULL_ERROR);
        }
        Resource resource = resourceService.selectByResourceId(resourceId);
        if (resource == null) {
            return ResultVOUtil.error(ResultEnum.NULL_ERROR);
        }
        ResourceDetailVO resourceDetailVO = new ResourceDetailVO();
        BeanUtils.copyProperties(resource, resourceDetailVO);
        resourceDetailVO.setResourcePrice(resourceDetailVO.getResourcePrice().multiply(Constant.POINT_CASH_RATE));
        User author = userService.selectUserByUserId(resource.getResourceAuthorId());
        resourceDetailVO.setResourceAuthorName(author.getUserName());
        return ResultVOUtil.success(resourceDetailVO);
    }


    @PostMapping
    @ResponseBody
    public ResultVO uploadResource(Resource resource, @RequestParam(name = "coverImage") MultipartFile coverImage, @RequestParam("resourceFile") MultipartFile resourceFile, HttpServletRequest request, HttpServletResponse response) {
        String userId = JwtUtil.verifyAccessToken(request, response);
        if (userId == null) {
            return ResultVOUtil.error(ResultEnum.NOT_LOGIN);
        }
        resource.setResourceAuthorId(userId);
        if (resource.getResourceName() == null || resource.getResourcePrice() == null || resource.getResourceTypeId() == null) {
            return ResultVOUtil.error(ResultEnum.RESOURCE_FIELD_EMPTY);
        }
        if (resourceFile.isEmpty()) {
            return ResultVOUtil.error(ResultEnum.ATTACHMENT_EMPTY_ERROR);
        }
        resource.setResourceState(ResourceStateEnum.WAIT_CHECK.getCode());
        try {
            String resourceId = UUIDUtil.getUUID();
            resource.setResourceId(resourceId);
            String originFileName = resourceFile.getOriginalFilename();
            System.out.println(originFileName);
            String fileSuffix = originFileName.substring(originFileName.lastIndexOf(".") + 1);
            String newFileName = resourceId + "." + fileSuffix;
            resourceFile.transferTo(new File(Constant.RESOURCE_FILE_DIRECTORY + newFileName));
            resource.setResourceFileName(newFileName);
            String coverName;
            if (!coverImage.isEmpty()) {
                String originCoverName = coverImage.getOriginalFilename();
                System.out.println(originCoverName);
                String coverSuffix = originCoverName.substring(originCoverName.lastIndexOf(".") + 1);
                // todo 用文件扩展名判断不安全
                Pattern pattern = Pattern.compile("jpg|png|jpeg");
                Matcher matcher = pattern.matcher(coverSuffix);
                if (!matcher.matches()) {
                    return ResultVOUtil.error(ResultEnum.IMAGE_FORMAT_ERROR);
                }
                coverName = UUIDUtil.getUUID() + "." + coverSuffix;
                coverImage.transferTo(new File(Constant.IMAGE_FILE_DIRECTORY + coverName));
            } else {
                coverName = Constant.DEFAULT_RESOURCE_COVER_NAME;
            }
            resource.setResourceCover(coverName);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultVOUtil.error(ResultEnum.ATTACHMENT_UPLOAD_FAILED);
        }
        try {
            resource.setResourcePrice(resource.getResourcePrice().divide(Constant.POINT_CASH_RATE));
            resourceService.saveResource(resource);
        } catch (Exception e) {
            return ResultVOUtil.error(ResultEnum.UPLOAD_FAILED);
        }
        return ResultVOUtil.success();
    }

    @GetMapping(value = "/download/{resourceId}")
    public ResultVO downloadResource(@PathVariable String resourceId, @RequestParam(required = false) String accessToken, HttpServletRequest request, HttpServletResponse response) {
        String userId;
        if (accessToken != null) {
            userId = JwtUtil.verifyAccessToken(accessToken);
        } else {
            userId = JwtUtil.verifyAccessToken(request, response);
        }
        if (StringUtils.isEmpty(userId)) {
            return ResultVOUtil.error(ResultEnum.NOT_LOGIN);
        }
        if (StringUtils.isEmpty(resourceId)) {
            return ResultVOUtil.error(ResultEnum.NULL_ERROR);
        }
        Resource resource = resourceService.selectByResourceId(resourceId);
        if (resource == null) {
            return ResultVOUtil.error(ResultEnum.NULL_ERROR);
        }
        User user = userService.selectUserByUserId(userId);
        Order order = orderService.selectOrderByUserAndGoods(userId, resourceId);
        if (!resource.getResourceAuthorId().equals(userId) && !"admin".equals(user.getUserRole()) && order == null) {
            return ResultVOUtil.error(ResultEnum.RESOURCE_NOT_BEEN_BOUGHT_ERROR);
        }
        try {
            //设置文件路径
            String fileName = resource.getResourceFileName();
            File file = new File(Constant.RESOURCE_FILE_DIRECTORY + fileName);
            if (file.exists()) {
                System.out.println("文件存在");
                // 设置强制下载不打开
                response.setContentType("application/force-download");
                // 设置文件名
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    os.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                return ResultVOUtil.error(ResultEnum.RESOURCE_FILE_NOT_EXISTS);
            }
        } catch (Exception e) {
            return ResultVOUtil.success();
        }
        return ResultVOUtil.success();
    }

}
